#include "ThreadPool.h"
#include "Constants.h"
#include "Filter.h"
#include "Queue.h"
#include "Connection.h"
#include "RequestHeader.h"
#include "RequestParameter.h"
#include "ResponseHeader.h"
#include "Global.h"
#include "HashSet.h"

int initPool(pool_t *pool, int num){
    pool->list = (pthread_t *)calloc(num, sizeof(pthread_t));
    pool->num = num;

    // 初始化队列
    memset(&pool->queue, 0, sizeof(pool->queue));

    pthread_mutex_init(&pool->lock, NULL);
    pthread_cond_init(&pool->cond, NULL);
    pthread_mutex_init(&pool->connlock, NULL);
    pthread_mutex_init(&pool->hashlock, NULL);
    
   
    for (int i = 0; i < num; i++){
        pthread_create(&pool->list[i], NULL, threadMain, (void *)pool);
    }
    
    pool->exitFlag = 0;
    return 0;
}




void* threadMain(void *ptr){
    pool_t *pool = (pool_t*)ptr;
    printf("线程，启动！\n");

    /* 数据库连接函数不是线程安全的，需要上锁 */
    pthread_mutex_lock(&pool->connlock);
    /* 连接MySQL */
    MYSQL *conn;
    MySQLDriver(&conn);
    pthread_mutex_unlock(&pool->connlock);

    while(1){
        pthread_mutex_lock(&pool->lock);
        
        // 退出标记为为1就不用wait了
        while(pool->queue.size <= 0 && pool->exitFlag == 0){
            // 取消点
            // 子线程有可能带锁死亡，别的线程就亖不了的
            pthread_cond_wait(&pool->cond, &pool->lock);
        }

        if(pool->exitFlag == 1){
            // 子线程退出
            pthread_mutex_unlock(&pool->lock);
            pthread_exit(NULL);
        }


        int net_fd = pool->queue.head->net_fd;
        deQueue(&pool->queue);
        pthread_mutex_unlock(&pool->lock);


        /* 查找当前用户在slot中的索引 */
        int idxInSlot;

        /* 加锁 */
        int isExist = hashmap_get(map, net_fd, &idxInSlot);
        
        if(isExist){
            /* 如果已经在队列中,要删除原先的 */
            hashset_remove(slotQueue->data[idxInSlot], idxInSlot);
        }
        /* 加锁 */
        hashset_add(slotQueue->data[curr], net_fd);
        hashmap_put(map,net_fd, curr);
        

        printf("有一个客户端到来\n");
        
        RequestHeader *header = createRequestHeader(-1, -1, -1, -1);
        /* 接收请求头 */
        memset(header, -1, sizeof(RequestHeader));
        int flag = recv(net_fd, header, sizeof(RequestHeader), MSG_WAITALL);
        if(flag == 0){
            break;
        }

        
        int ret = handleMapping(net_fd, header, conn);

        // 此处需要修改，把响应加到handleMapping()里面
        if(ret == 0){
            sendResponseHeader(net_fd, 0, "error\n");
        }else{
            response(net_fd, header->command, ret);
        }

    }
    pthread_mutex_lock(&pool->connlock);
    mysql_close(conn);
    pthread_mutex_unlock(&pool->connlock);

    return (void*)0;
}
